//
//  CZEmoticon.swift
//  表情键盘-新建项目
//
//  Created by zhangping on 15/10/21.
//  Copyright © 2015年 zhangping. All rights reserved.
//

import UIKit

/// 表情包 模型
class CZEmoticonPackage: NSObject {
    
    // MARK: - 属性
    /// Emoticons.bundle的路径
    private static let bundlePath = NSBundle.mainBundle().pathForResource("Emoticons", ofType: "bundle")!
    
    /// 表情包 文件夹 名称
    var id: String?
    
    /// 表情包 名称
    var group_name_cn: String?
    
    // 表情模型 数组
    var emoticons: [CZEmoticon]?
    
    // MARK: - 构造函数
    init(id: String) {
        self.id = id
    }
    
    // MARK: - 对象打印方法
    /// 对象打印方法
    override var description: String {
        return "\n\t表情包模型: id:\(id), group_name_cn:\(group_name_cn), emoticons:\(emoticons)"
    }
    
    // 每次从磁盘加载表情包耗性能,第一次从本地加载表情包数据,保存到内存中.以后重内存中加载
    static let packages = CZEmoticonPackage.loadPackages()
    
    /**
    加载 所有的 表情包
    - returns: 表情包数组
    */
    class func loadPackages() -> [CZEmoticonPackage] {
        print("加载表情包")
        // 加载 Emoticons.bundle/emoticons.plist文件

        let plistPath = (bundlePath as NSString).stringByAppendingPathComponent("emoticons.plist")
        
        // 加载 emoticons.plist 里面的内容
        let emoticonDict = NSDictionary(contentsOfFile: plistPath)!
//        print("emoticonDict: \(emoticonDict)")
        
        // 获取 packages 数组
        let packageArr = emoticonDict["packages"] as! [[String: AnyObject]]
        
        // 定义表情包数组
        var packages = [CZEmoticonPackage]()
        
        // 创建 `最近` 表情包
        let recent = CZEmoticonPackage(id: "")
        
        // 初始化 表情模型 数组
        recent.emoticons = [CZEmoticon]()
        
        // 设置表情包名称
        recent.group_name_cn = "最近"
        
        // 追加空表情和删除按钮
        recent.appendEmptyEmoticon()
        
        // 添加到表情包数组
        packages.append(recent)
        
        // 遍历数组,获取到每个表情包得名称
        for dict in packageArr {
            // 取出字典里面的 id 对应的value, 表情包文件夹 名称
            let id = dict["id"] as! String
            
            // 创建表情包
            let package = CZEmoticonPackage(id: id)
            
            package.loadEmoticons()
            
            // 添加到表情包数组
            packages.append(package)
        }
        
        return packages
    }
    
    /**
    加载表情包里面的所有表情模型和表情包名称
    */
    private func loadEmoticons() {
        // 获取 表情包文件夹/info.plist 内容
        // info.plist的路径 = bundlePath + 表情包名称 + info.plist
        let infoPath = ((CZEmoticonPackage.bundlePath as NSString).stringByAppendingPathComponent(id!) as NSString).stringByAppendingPathComponent("info.plist")
        
        // 加载 info.plist
        let infoDict = NSDictionary(contentsOfFile: infoPath)!
        
        // 获取表情包名称,赋值给当前表情包模型
        group_name_cn = infoDict["group_name_cn"] as? String
        
        // 获取 emoticons 数组
        let emoticonsArr = infoDict["emoticons"] as! [[String: String]]
        
        // 创建表情模型数组
        emoticons = [CZEmoticon]()
        
        // 记录表情在当前页的序号
        var index = 0
        
        // 遍历,加载表情模型
        for dict in emoticonsArr {
            // 表情字典 转 模型, 添加到表情模型数组里面
            emoticons?.append(CZEmoticon(id: id, dict: dict))
            
            index++
            
            // 判断当前是否是最后一个位置
            if index == 20 {
                // 添加一个删除按钮
                emoticons?.append(CZEmoticon(removeEmoticon: true))
                
                // 重置 index
                index = 0
            }
        }
        
        // 当表情加载完成的时候判断是否正好满一页,不满一页的添加空白按钮,并在最后位置添加删除按钮
        appendEmptyEmoticon()
    }
    
    /// 当表情加载完成的时候判断是否正好满一页,不满一页的添加空白按钮,并在最后位置添加删除按钮
    private func appendEmptyEmoticon() {
        // 获取到最后一页的个数
        let count = emoticons!.count % 21
        
        // count > 0 表示最后一页有 count 个表情, 没满一页. 需要追加空白按钮
        // emoticons!.count = 是 最近 表情包,也需要追加
        if count > 0 || emoticons!.count == 0 {
            // 追加多少个空白按钮?
            // count == 1 需要追加20 - 1 = 19个空白按钮和一个删除按钮 1..<20
            // count == 2 需要追加20 - 2 = 18个空白按钮和一个删除按钮 2..<20
            for _ in count..<20 {
                emoticons?.append(CZEmoticon(removeEmoticon: false))
            }
            
            // 追加删除按钮
            emoticons?.append(CZEmoticon(removeEmoticon: true))
        }
    }
    
    /// 添加最近使用表情
    class func addFavorate(emoticon: CZEmoticon) {
        // 删除按钮不添加到最近表情
        if emoticon.removeEmoticon {
            return
        }
        
        // 使用次数加1
        emoticon.times++
        
        // 获取到最近表情包里面的表情数组
        var recentEmoticonPackage = packages[0].emoticons!
        
        // 移除 删除按钮
        let removeEmoticon = recentEmoticonPackage.removeLast()
        
        // 如果最近表情包已经存在,不需要添加
        let contains = recentEmoticonPackage.contains(emoticon)
        if !contains {
            // 向最近表情包添加表情
            recentEmoticonPackage.append(emoticon)
        }
        
        // 排序
        recentEmoticonPackage = recentEmoticonPackage.sort({ (e1, e2) -> Bool in
            return e1.times > e2.times
        })
        
        // 保证 最近 只有 21个按钮,最后一个是删除按钮
        if !contains {
            recentEmoticonPackage.removeLast()
        }
        
        // 添加 删除按钮
        recentEmoticonPackage.append(removeEmoticon)
        
        // 重新赋值回去
        packages[0].emoticons = recentEmoticonPackage
        
//        print("最近表情: \(packages[0].emoticons)")
    }
}

/*
    表情模型能显示图片和emoji
    扩展表情模型使表情模型能显示删除按钮,和空白按钮
*/
/// 表情 模型
class CZEmoticon: NSObject {
    // MARK: - 属性
    /// 表情包 文件夹名称
    var id: String?
    
    /// 表情名称, 用于网络传输
    var chs: String?
    
    /// 表情图片名称, 在手机上显示表情图片
    var png: String?
    
    /// 只读计算型属性: png的全路径
    var pngPath: String? {
        // png 不一定有值
        if png == nil {
            return nil
        }
        
        // png 全路径 = bundlePath + 表情包名称 + png名称
        return ((CZEmoticonPackage.bundlePath as NSString).stringByAppendingPathComponent(id!) as NSString).stringByAppendingPathComponent(png!)
    }
    
    /// emoji 16进制字符串
    var code: String? {
        didSet {
            // 将 code 转成 emoji字符串
            
            let scanner = NSScanner(string: code!)
            
            var result: UInt32 = 0
            scanner.scanHexInt(&result)
            
            emoji = "\(Character(UnicodeScalar(result)))"
        }
    }
    
    /// emoji字符串
    var emoji: String?
    
    /// 是否是删除按钮, true表示删除按钮
    var removeEmoticon: Bool = false
    
    /// 使用次数
    var times = 0
    
    // MARK: - 字典转模型
    /// 构造函数:只会给removeEmoticon属性赋值, removeEmoticon = true 表示删除按钮, false表示空白按钮
    init(removeEmoticon: Bool) {
        self.removeEmoticon = removeEmoticon
        super.init()
    }
    
    /// 字典转模型,可能是表情图片,也可能是emoji
    init(id: String?, dict: [String: AnyObject]) {
        self.id = id
        super.init()
        
        // KVC
        setValuesForKeysWithDictionary(dict)
    }
    
    // 字典的key在模型中找不到对应的属性
    override func setValue(value: AnyObject?, forUndefinedKey key: String) {}
    
    /// 打印对象
    override var description: String {
        return "\n\t\t: 表情模型:chs:\(chs), png:\(png), code:\(code), removeEmoticon:\(removeEmoticon)"
    }
}
